package com.weipt.threadpool;

import java.util.concurrent.*;

/**
 * @author peter.wei 2020/08/27 09:25
 * @version 1.0
 * @company 终生学习
 * @description <br>peter.wei 2020/08/27 09:25
 **/
public class TestThreadPool {

    //指定核心线程数
    //cpu是多少线程，就获取多少个
    private static final int corePoolSize = Runtime.getRuntime().availableProcessors();

    //最大线程数
    private static final int maximumPoolSize = 2*corePoolSize;

    //时间
    private static final long keepAliveTime = 0L;  //直接不等待退出
    private static final TimeUnit timeUnit = TimeUnit.MILLISECONDS;

    /**
     * 创建队列
     **/
    //是一个基于数组结构的有界阻塞队列，此队列按 FIFO（先进先出）原则对元素进行排序。提前指定，不太友好，但可控
    private static final BlockingQueue<Runnable> arrayBlockingQueue = new ArrayBlockingQueue<>(10);
    //一个基于链表结构的阻塞队列，此队列按FIFO （先进先出） 排序元素，吞吐量通常要高于ArrayBlockingQueue。
    // 静态工厂方法Executors.newFixedThreadPool()使用了这个队列
    //Integer.MAX_VALUE
    private static final BlockingQueue<Runnable> linkedBlockingQueue = new LinkedBlockingQueue<>();
    //一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作，否则插入操作一直处于阻塞状态，
    // 吞吐量通常要高于LinkedBlockingQueue，静态工厂方法Executors.newCachedThreadPool使用了这个队列。
    private static final BlockingQueue<Runnable> synchronousQueue = new SynchronousQueue<>();
    //一个具有优先级的无限阻塞队列。
    private static final BlockingQueue<Runnable> priorityBlockingQueue = new PriorityBlockingQueue<>();

    //创建线程池单例
    private static final ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, linkedBlockingQueue, new LocalThreadFactory());

    /**
     核心线程数10，最大线程数30，keepAliveTime是3秒
     随着任务数量不断上升，线程池会不断的创建线程，直到到达核心线程数10，就不创建线程了，
     这时多余的任务通过加入阻塞队列来运行，
     当超出阻塞队列长度+核心线程数时，
     这时不得不扩大线程个数来满足当前任务的运行，这时就需要创建新的线程了（最大线程数起作用），上限是最大线程数30
     那么超出核心线程数10并小于最大线程数30的可能新创建的这20个线程相当于是“借”的，如果这20个线程空闲时间超过keepAliveTime，就会被退出
    **/


    //禁止外部创建
    public TestThreadPool() throws Exception {
        throw new Exception("非法操作！！！");
    }
    
    public static void submit(Runnable runnable){
        threadPoolExecutor.submit(runnable);
    }

    public static <T>Future<T> submit(Runnable runnable, T result){
        return threadPoolExecutor.submit(runnable, result);
    }

    public <T> Future<T> submit(Callable<T> task) {
        return threadPoolExecutor.submit(task);
    }

    public static class LocalThreadFactory implements ThreadFactory {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("pool-log-thread");
                thread.setPriority(Thread.MIN_PRIORITY); //设置线程优先级,根据实际业务定
                return thread;
            }
    }
}

class Test{
    private static void test1(){
        TestThreadPool.submit(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("当前i:"+i);
            }
        });

        TestThreadPool.submit(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("当前j:"+i);
            }
        });
    }

    public static void main(String[] args) {
        test1();
    }
}